package com.shawn.dubbo.api;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shawn.dubbo.mapper.OptionsMapper;
import com.shawn.dubbo.mapper.QuestionnaireMapper;
import com.shawn.dubbo.mapper.SoulQuestionMapper;
import com.shawn.dubbo.mapper.UserTestMapper;
import com.shawn.model.dto.Answer;
import com.shawn.model.entity.*;
import com.shawn.model.vo.OptionsVo;
import com.shawn.model.vo.SoulQuestionVo;
import com.shawn.model.vo.SoulResultVo;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author shawn
 * @date 2022年 11月 12日 16:31
 */

@DubboService
public class QuestionnaireApiImpl implements QuestionnaireApi{


    @Autowired
    private QuestionnaireMapper questionnaireMapper;

    @Autowired
    private SoulQuestionMapper soulQuestionMapper;

    @Autowired
    private UserTestMapper userTestMapper;

    @Autowired
    private OptionsMapper optionsMapper;


    @Override
    public List<Questionnaire> getQuestionnaire() {
        List<Questionnaire> list = questionnaireMapper.selectList(new LambdaQueryWrapper<>());
        return list;
    }

    /**
     * 得到灵魂问题
     *
     * @param ids id
     * @return {@link Map}<{@link Long}, {@link List}<{@link SoulQuestion}>>
     */
    @Override
    public Map<Long, List<SoulQuestionVo>> getSoulQuestions(List<Long> ids) {

        List<SoulQuestion> soulQuestions = soulQuestionMapper.selectList(new LambdaQueryWrapper<>());
        //获取所有的选项
        List<Options> optionsList = optionsMapper.selectList(new LambdaQueryWrapper<>());
        Map<Long,List<SoulQuestionVo>> map = new HashMap<>();
        for (Long id : ids) {
            //筛选出问卷对应的问题
            List<SoulQuestion> questions = soulQuestions.stream().filter(q -> Objects.equals(id, q.getQId())).collect(Collectors.toList());
            //遍历所有问题获取对应选项
            List<SoulQuestionVo> questionList = questions.stream().map(q -> {
                List<OptionsVo> list = new ArrayList<>();
                for (Options option : optionsList) {
                    if (Objects.equals(q.getId(), option.getSqId())) {
                        list.add(OptionsVo.init(option));
                    }
                }
                return SoulQuestionVo.init(q, list);
            }).collect(Collectors.toList());
            map.put(id,questionList);
        }
        return map;
    }

    /**
     * 返回所有的用户测试表
     *
     * @param userId 用户id
     * @return {@link List}<{@link UserTest}>
     */
    @Override
    public List<UserTest> getUserTests(Long userId) {
        LambdaQueryWrapper<UserTest> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserTest::getUserId,userId);
        return userTestMapper.selectList(wrapper);
    }

    /**
     * 根据题目id获取问卷id
     *
     * @param questionId 问题id
     * @return {@link Long}
     */
    @Override
    public Long getQuestionnaireId(String questionId) {
        SoulQuestion soulQuestion = soulQuestionMapper.selectById(questionId);
        return soulQuestion.getQId();
    }

    /**
     * 得到分数由ids
     *
     * @param optionIds 选择id
     * @return {@link Integer}
     */
    @Override
    public Integer getScoreByIds(List<String> optionIds) {
        return optionsMapper.getScoreByIds(optionIds);
    }

    /**
     * 保存或更新用户测试结果
     *
     * @param userTest 用户测试
     */
    @Override
    public void save(UserTest userTest) {
        UserTest test = userTestMapper.selectById(userTest.getId());
        if (Objects.isNull(test)){
            userTestMapper.insert(userTest);
        }else {
            userTestMapper.updateById(userTest);
        }
    }

    /**
     * 根据报告id获取所有相似用户id
     *
     * @param id id
     * @return {@link List}<{@link Long}>
     */
    @Override
    public List<Long> getSimilar(String id) {
        LambdaQueryWrapper<UserTest> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserTest::getReportId,id);
        List<UserTest> tests = userTestMapper.selectList(wrapper);
        return tests.stream().map(UserTest::getUserId).collect(Collectors.toList());
    }
}
